import fetch from 'node-fetch';
import common from '../../lib/common/common.js';
import Cfg from '../../lib/config/config.js';

export class ExamplePlugin extends plugin {
    constructor() {
        super({
            name: "qq",
            desc: "空间自动点赞和删除说说",
            event: "message",
            priority: -Infinity,
            rule: [
                {
                    reg: /^执行空间点赞/,
                    fnc: "handleSignIn"
                },
                {
                    reg: /^执行删说说$/,
                    fnc: "deleteMood"
                },
                {
                    reg: /^给我?(qzone|空间|Qzoen)(赞我|点赞)(qzone|空间|Qzoen)?$/,
                    fnc: "zanwoqzone"
                }
            ]
        });
        this.task = {
            cron: '0 0 0/4 * * ?',
            name: '自动点赞说说',
            fnc: () => this.handleSignIn()
          };
    }


    async zanwoqzone(e) {
        let key = `qzone:${e.user_id}`;
        if (await redis.get(key)) return e.reply(`当前正在为您执行空间点赞请稍等...`, true)
        redis.set(key, "1");
        e.reply(`正在给你空间点赞请稍后...`, true);
        const targetUin = e.user_id;
        let totalLikedCounts = [];
    
        let uins = this.getUins(Cfg['qq']);
        for (const uin of uins) {
            if (!Bot[uin]) {
                logger.error(`未找到QQ号${uin}对应的Bot实例，跳过此账号`);
                continue;
            }
    
            const cookiesAndBkn = await this.getOrExtractCookies(uin);
            if (!cookiesAndBkn) {
                logger.error(`无法为QQ号${uin}获取有效的Cookies和bkn，跳过此账号`);
                continue;
            }
    
            const { cookies, bkn } = cookiesAndBkn;
            let likedCount = 0;
    
            try {
                const response = await fetch(`https://user.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6?uin=${targetUin}&ftype=1&sort=0&pos=0&num=30&replynum=100&g_tk=${bkn}&code_version=1&format=json&need_private_comment=1`, {
                    headers: {
                        'Cookie': cookies
                    }
                });
    
                if (response.ok) {
                    const data = await response.json();
    
                    if (data.msglist && Array.isArray(data.msglist)) {
                        for (const msg of data.msglist) {
                            await common.sleep(3000); 
                            await this.likePost(msg.tid, targetUin, bkn, cookies, uin);
                            likedCount++;
                        }
                        logger.mark(`[QQ:${uin}] 已成功点赞 ${likedCount} 条说说`);
                        if (likedCount > 0) {
                            totalLikedCounts.push(likedCount);
                        }
                    } else {
                        logger.warn(`[QQ:${uin}] 在处理赞我空间时没有找到动态列表：${data.message}`);
                    }
                } else {
                    logger.error(`[QQ:${uin}] 获取动态列表失败: ${data.message}`);
                }
            } catch (error) {
                logger.error(`[QQ:${uin}] 获取动态列表时出错: ${error.message}`);
            }
        }
        const totalLikes = totalLikedCounts.reduce((acc, curr) => acc + curr, 0);
        let replyMessage = `点赞操作完成。\n共有 ${totalLikedCounts.length} 个QQ账号点赞  ${(totalLikes / totalLikedCounts.length)} 条说说点赞成功。`
        redis.del(key, "1");
        e.reply(replyMessage, true);
    }


    async handleSignIn() {
        let uins = this.getUins(Cfg['qq']);
        for (const uin of uins) {
            if (!Bot[uin]) {
                logger.error(`未找到QQ号${uin}对应的Bot实例，跳过此账号`);
                continue;
            }

            const cookiesAndBkn = await this.getOrExtractCookies(uin);
            if (!cookiesAndBkn) {
                logger.error(`无法为QQ号${uin}获取有效的Cookies和bkn，跳过此账号`);
                continue;
            }

            const { cookies, bkn } = cookiesAndBkn;

            const friendsList = Array.from(Bot[uin].fl.keys());
            for (const friend of friendsList) {
                try {
                    const response = await fetch(`https://user.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6?uin=${friend}&ftype=1&sort=0&pos=0&num=10&replynum=100&g_tk=${bkn}&code_version=1&format=json&need_private_comment=1`, {
                        headers: {
                            'Cookie': cookies
                        }
                    });
                    await common.sleep(15000);

                    const data = await response.json();

                    if (data.msglist && Array.isArray(data.msglist)) {
                        for (const msg of data.msglist) {
                            await common.sleep(3000);
                            await this.likePost(msg.tid, friend, bkn, cookies, uin);
                        }
                    } else {
                        logger.warn(`[QQ:${uin}] 的好友 [UIN:${friend}] 没有找到动态列表:\n${data.message}`);
                    }
                } catch (error) {
                    logger.error(`[QQ:${uin}] 在处理好友 [UIN:${friend}] 时出错: ${error.message}`);
                }
            }
        }
    }


      async deleteMood(e) {
        if (!e.isMaster) return e.reply('你谁啊你删', true);
        e.reply(`正在删除所有说说(请确保说说状态为公开或者仅好友可见)...`, true);
        const uin = e.self_id;
    
        const cookiesAndBkn = await this.getOrExtractCookies(uin);
        if (!cookiesAndBkn) {
            e.reply(`无法为QQ号${uin}获取有效的Cookies和bkn，删除说说失败`, true);
            return;
        }
    
        const { cookies, bkn } = cookiesAndBkn;
    
        while (true) {
            try {
                const response = await fetch(`https://user.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6?uin=${uin}&ftype=1&sort=0&pos=0&num=30&replynum=1000&g_tk=${bkn}&code_version=1&format=json&need_private_comment=1`, {
                    headers: {
                        'Cookie': cookies
                    }
                });
    
                if (response.ok) {
                    const data = await response.json();
                    if (data.msglist && Array.isArray(data.msglist)) {
                        for (const msg of data.msglist) {
                            await common.sleep(3000); 
                            await this.deleteSpecificMood(msg.tid, uin, bkn, cookies);
                        }
                        if (data.msglist.length < 5) break;
                    } else {
                        logger.warn(`[QQ:${uin}] 获取动态列表时没有找到动态列表\n${data.message}`);
                        break;
                    }
                } else {
                    logger.error(`[QQ:${uin}] 获取动态列表失败: 状态码 ${response.status}`);
                    break;
                }
            } catch (error) {
                logger.error(`[QQ:${uin}] 获取动态列表时出错: ${error.message}`);
                break;
            }
            await common.sleep(5000); 
        }
    
        e.reply(`已成功删除所有说说`, true);
    }

    async deleteSpecificMood(tid, uin, bkn, cookies) {
        const url = `https://user.qzone.qq.com/proxy/domain/taotao.qzone.qq.com/cgi-bin/emotion_cgi_delete_v6?&g_tk=${bkn}`;
        const data = {
            hostuin: uin,
            tid: tid,
            t1_source: "1",
            code_version: "1",
            format: "fs",
            qzreferrer: `https://user.qzone.qq.com/${uin}/311`
        };
        const headers = {
            "Host": "user.qzone.qq.com",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0",
            "Accept": "*/*",
            "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
            "Accept-Encoding": "gzip, deflate, br, zstd",
            "Content-Type": "application/x-www-form-urlencoded",
            "Connection": "keep-alive",
            "Referer": `https://user.qzone.qq.com/${uin}/311`,
            "Sec-Fetch-Dest": "document",
            "Sec-Fetch-Mode": "no-cors",
            "Sec-Fetch-Site": "same-origin",
            "Pragma": "no-cache",
            "Cache-Control": "no-cache",
            "Cookie": cookies
        };

        try {
            const response = await fetch(url, {
                method: 'POST',
                headers: headers,
                body: new URLSearchParams(data)
            });

            if (response.status === 200) {
                logger.mark(`[QQ:${uin}] 删除说说ID [${tid}] 成功`);
            } else {
                logger.error(`[QQ:${uin}] 删除说说ID [${tid}] 失败: 状态码 ${response.status}`);
            }
        } catch (error) {
            logger.error(`[QQ:${uin}] 删除说说ID [${tid}] 时出错: ${error.message}`);
        }
    }

    async getOrExtractCookies(uin) {
        let cookies, bkn;
        if (Bot[uin].cookies && Bot[uin].cookies["qzone.qq.com"]) {
            cookies = Bot[uin].cookies["qzone.qq.com"];
            const skeyMatch = /skey=([^;]+)/.exec(cookies);
            if (skeyMatch) {
                bkn = GTK(skeyMatch[1]);
                return { cookies, bkn };
            }
        }
        const apiResult = await Bot[uin].sendApi('get_cookies', {"domain": "qzone.qq.com"});
        if (apiResult.retcode === 0) {
            cookies = this.extractCookies(apiResult.data.cookies);
            bkn = apiResult.data.bkn;
            return { cookies, bkn };
        }

        return null;
    }

    extractCookies(cookiesStr) {
        const cookies = {};
        cookiesStr.split('; ').forEach(cookie => {
            const [key, value] = cookie.split('=');
            cookies[key] = value;
        });

        if (!cookies.uin || !cookies.skey || !cookies.p_skey) {
            return null;
        }

        return `uin=${cookies.uin}; skey=${cookies.skey}; p_skey=${cookies.p_skey}; p_uin=${cookies.uin}`;
    }
    getUins(qqNumbers) {
        if (Array.isArray(qqNumbers)) {
          return qqNumbers;
        } else if (typeof qqNumbers === 'number' || typeof qqNumbers === 'string') {
          return [qqNumbers];
        }
        return [];
      }
    async likePost(tid, uin, bkn, cookies, qq) {
        const url = `https://user.qzone.qq.com/proxy/domain/w.qzone.qq.com/cgi-bin/likes/internal_dolike_app?g_tk=${bkn}`;
        const qzreferrer = `https://user.qzone.qq.com/${uin}`;
        const unikey = `http://user.qzone.qq.com/${uin}/mood/${tid}`;
        const abstime = Math.floor(Date.now() / 1000);

        try {
            const response = await fetch(url, {
                method: 'POST',
                headers: {  
            "Host": "h5.qzone.qq.com",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0",
            "Accept": "textml,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
            "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
            "Accept-Encoding": "gzip, deflate, br",
            "Connection": "keep-alive",
            "Cache-Control": "no-cache",
            "Origin": "https://user.qzone.qq.com",
            "Content-Type": "application/x-www-form-urlencoded",
            "Sec-Fetch-Dest": "iframe",
            "Sec-Fetch-Mode": "navigate",
            "Upgrade-Insecure-Requests": "1",
            "Sec-Fetch-Site": "same-origin",
            'Cookie': cookies
                },
                body: new URLSearchParams({
                    qzreferrer,
                    opuin: uin,
                    unikey,
                    curkey: unikey,
                    from: '1',
                    appid: '311',
                    typeid: '0',
                    abstime,
                    fid: tid,
                    active: '0',
                    fupdate: '1'
                })
            });

            const text = await response.text();
            if (text.includes('"message":"succ"')) {
                logger.mark(`[QQ:${qq}] 对好友 [UIN:${uin}] 的动态ID [${tid}] 点赞成功`);
            } else {
                logger.error(`[QQ:${qq}] 对好友 [UIN:${uin}] 的动态ID [${tid}] 点赞失败`);
            }
        } catch (error) {
            logger.error(`[QQ:${qq}] 在处理好友 [UIN:${uin}] 的动态ID [${tid}] 时出错: ${error.message}`);
        }
    }
}

function GTK(skey) {
    let hash = 5381;
    for (let i = 0; i < skey.length; i++) {
        hash += (hash << 5 & 2147483647) + skey.charCodeAt(i) & 2147483647;
        hash &= 2147483647;
    }
    return hash & 2147483647;
}